#include "IHM.h"
#include "fonctions.h"
#include <string.h>

struct sWidget_Info
{

    GtkWidget *parcourir;
    GtkWidget *combobox;
    GtkWidget *entry;
    GtkWidget *verif_entry;

};

typedef struct sWidget_Info Widget_Info;

static void boiteDialogue_erreur(const char *msg_erreur) {
/** Postcondition : msg_erreur non vide
  * Precondition : une fenetre d'erreur avec le message c'est affiché
  */

    GtkWidget *fen_erreur;

    fen_erreur = gtk_message_dialog_new(GTK_WINDOW(NULL), GTK_DIALOG_MODAL,GTK_MESSAGE_ERROR,GTK_BUTTONS_OK, "Erreur :\n%s", msg_erreur);
    gtk_window_set_title(GTK_WINDOW(fen_erreur), "CLYD - Erreur");
    gtk_window_set_icon_from_file(GTK_WINDOW(fen_erreur), "./image/icon.png", NULL);

    gtk_dialog_run(GTK_DIALOG(fen_erreur));
    gtk_widget_destroy(fen_erreur);

}

static void boiteDialogue_info(const char *msg_info) {
/** Postcondition : msg_info non vide
  * Precondition : une fenetre d'information avec le message c'est affiché
  */

    GtkWidget *fen_info;

    fen_info = gtk_message_dialog_new(GTK_WINDOW(NULL), GTK_DIALOG_MODAL,GTK_MESSAGE_INFO, GTK_BUTTONS_OK, "Information :\n%s", msg_info);
    gtk_window_set_title(GTK_WINDOW(fen_info), "CLYD - Information");
    gtk_window_set_icon_from_file(GTK_WINDOW(fen_info), "./image/icon.png", NULL);

    gtk_dialog_run(GTK_DIALOG(fen_info));
    gtk_widget_destroy(fen_info);

}

static void cliqueC(GtkWidget *widget, gpointer *data) {
/** Postcondition : wigdet et dat a initialisé
  * Precondition : a appliqué l'algorithme de cryptage sur le fichier selectionné.
  */

    bool res = false;

    // Chargement des arguments de la fonction.

    char * fichier = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(((Widget_Info *)data)->parcourir));

    char *algo = gtk_combo_box_get_active_text(GTK_COMBO_BOX (((Widget_Info *)data)->combobox));

    unsigned char *clef = (unsigned char *) gtk_entry_get_text(GTK_ENTRY(((Widget_Info *)data)->entry));

    unsigned char *clef_verif = (unsigned char *) gtk_entry_get_text(GTK_ENTRY(((Widget_Info *)data)->verif_entry));

    if(strcmp((char *) clef, (char *) clef_verif) != 0) { // On vérifie que l'utilisateur a entré les meme mots de passes

        boiteDialogue_erreur("Vérifiez votre mot de passe.");
        return;
    }

    if(strcmp(algo, "DES") == 0)
        res = cbc_des_c(fichier, clef);

    else if(strcmp(algo, "3DES") == 0)
        res = cbc_troisdes_c(fichier, clef);

    else if(strcmp(algo, "CESAR") == 0)
        res = cesar_c(fichier, clef);

    else
        res = cbc_des_c(fichier, clef);

    if(res) // affichage du résultat du cryptage.
        boiteDialogue_info("Le cryptage a été effectué avec succès !\n");
    else
        boiteDialogue_erreur("Le cryptage n'a pas pu être effectué.\n\
                            Veuillez vérifier si le fichier existe toujours.");
}


static void cliqueD(GtkWidget *widget,gpointer *data) {
/** Postcondition : wigdet et dat a initialisé
  * Precondition : a appliqué l'algorithme de cryptage sur le fichier selectionné.
  */

    bool res = false;

    // Chargement des arguments de la fonction.

    char * fichier = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(((Widget_Info *)data)->parcourir));

    gchar *algo = gtk_combo_box_get_active_text(GTK_COMBO_BOX (((Widget_Info *)data)->combobox));

    unsigned char *clef = (unsigned char *) gtk_entry_get_text(GTK_ENTRY(((Widget_Info *)data)->entry));

    unsigned char *clef_verif = (unsigned char *) gtk_entry_get_text(GTK_ENTRY(((Widget_Info *)data)->verif_entry));

    if(strcmp((char *) clef, (char *) clef_verif) != 0) { // On vérifie que l'utilisateur a entré les meme mots de passes

        boiteDialogue_erreur("Vérifiez votre mot de passe.");

        return;
    }

    if(strcmp(algo, "DES") == 0)
        res = cbc_des_d(fichier, clef);

    else if(strcmp(algo, "3DES") == 0)
        res = cbc_troisdes_d(fichier, clef);

    else if(strcmp(algo, "CESAR") == 0)
        res = cesar_d(fichier, clef);

    else
        res = cbc_des_d(fichier, clef);


    if(res) // affichage du résultat du décryptage.
        boiteDialogue_info("Le décryptage a été effectué avec succès !\n");
    else
        boiteDialogue_erreur("Le décryptage n'a pas pu être effectué.\n\
                            Veuillez vérifier si le fichier existe toujours.");
}

static void cliqueA(GtkWidget *widget, gpointer *data) {
/** Postcondition : wigdet et dat a initialisé
  * Precondition : Le survole de la souris sur la combobox affiche le bon message en fonction de l'algorithme sélectionné.
  */


    GtkTooltips * bulle;
    bulle = gtk_tooltips_new();

    char *algo = gtk_combo_box_get_active_text(GTK_COMBO_BOX(data));

    if(strcmp(algo, "DES") == 0)
        // Bulle: Algorithme DES
        gtk_tooltips_set_tip(bulle, GTK_WIDGET(data), "Algorithme DES : Très bonne sécurité.", NULL);
    else if(strcmp(algo, "3DES") == 0)
        // Bulle: Algorithme 3DES
        gtk_tooltips_set_tip(bulle, GTK_WIDGET(data), "Algorithme 3DES : Très bonne sécurité.\nAttention cela peut prendre du temps.", NULL);
    else if(strcmp(algo, "CESAR") == 0)
        // Bulle: Algorithme CESAR
        gtk_tooltips_set_tip(bulle, GTK_WIDGET(data), "Algorithme CESAR : Mauvaise sécurité. Ne pas utiliser pour des fichiers sensibles.", NULL);
    else
        // Bulle: Algorithme par défaut
        gtk_tooltips_set_tip(bulle, GTK_WIDGET(data), "Algorithme DES : Très bonne sécurité.", NULL);
}

void g_interface(int *argc, char ***argv)
{

    gtk_init(argc, argv);

    GtkWidget *fenetrePrincipale = NULL;
    fenetrePrincipale = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    GtkWidget *vbox = NULL;
    vbox = gtk_vbox_new(TRUE, 2);
    gtk_box_set_homogeneous(GTK_BOX(vbox), FALSE); // Prend la place minimum pour les éléments de la vbox
    gtk_container_add(GTK_CONTAINER(fenetrePrincipale), vbox);

    /***** Logo CLYD *****/


    GtkWidget *logo = NULL;
    logo = gtk_image_new_from_file("./image/logo.png"); // Chemin du fichier image
    gtk_box_pack_start(GTK_BOX(vbox), logo, TRUE, TRUE, 0);


    /***** Création du champ parcourir *****/

    // Box pour le champ

    GtkWidget *hbox = NULL;
    hbox = gtk_hbox_new(TRUE, 2);
    gtk_box_pack_start(GTK_BOX (vbox), hbox, FALSE, TRUE, 0);

    // Explication du champ

    GtkWidget *l_ficCrypt = NULL;
    l_ficCrypt = gtk_label_new(NULL);
    gtk_label_set_markup (GTK_LABEL (l_ficCrypt), "Fichier à crypter ou décrypter :");
    gtk_box_pack_start(GTK_BOX (hbox), l_ficCrypt, FALSE, TRUE, 1);

    // Widget pour parcourir

    GtkWidget *parcourir = NULL;
    parcourir = gtk_file_chooser_button_new(("Choisissez un fichier"), GTK_FILE_CHOOSER_ACTION_OPEN);

    //gtk_file_chooser_set_select_multiple(parcourir, TRUE);
    gtk_box_pack_start(GTK_BOX (hbox), parcourir, FALSE, TRUE, 2);

    /***** Champ pour le choix du script ou de l'algorithme de cryptage *****/

    GtkWidget *hbox2 = NULL;
    hbox2 = gtk_hbox_new(TRUE, 2);
    gtk_box_pack_start(GTK_BOX (vbox), hbox2, FALSE, TRUE, 1);

    // label du a zone de choix
    GtkWidget *l_champ2 = NULL;
    l_champ2 = gtk_label_new(NULL);
    gtk_label_set_markup (GTK_LABEL (l_champ2), "Choix de l'algorithme :");
    gtk_box_pack_start(GTK_BOX(hbox2), l_champ2, FALSE, TRUE, 0);

    // Création de la combobox

    GtkWidget *combo2_algo = gtk_combo_box_new_text ();

    gtk_combo_box_append_text(GTK_COMBO_BOX (combo2_algo), "DES (par défaut)");
    gtk_combo_box_append_text(GTK_COMBO_BOX (combo2_algo), "3DES");
    gtk_combo_box_append_text(GTK_COMBO_BOX (combo2_algo), "CESAR");
    gtk_signal_connect (GTK_OBJECT (combo2_algo), "changed", G_CALLBACK (cliqueA), combo2_algo);
    gtk_combo_box_set_active(GTK_COMBO_BOX (combo2_algo), 0);

    gtk_box_pack_start(GTK_BOX(hbox2), combo2_algo, FALSE, TRUE, 1);

    /***** Champ de mot de passe *****/

    GtkWidget *hbox3 = NULL;
    hbox3 = gtk_hbox_new(TRUE, 2);
    gtk_box_pack_start(GTK_BOX (vbox), hbox3, FALSE, TRUE, 2);

    // label du a zone de choix

    GtkWidget *label_mdp = NULL;
    label_mdp = gtk_label_new(NULL);
    GtkTooltips * bulle;
    bulle = gtk_tooltips_new();
    gtk_label_set_markup (GTK_LABEL (label_mdp), "Mot de passe :");
    gtk_tooltips_set_tip(bulle, label_mdp, "Saisir un mot de passe", NULL); // Bulle
    gtk_box_pack_start(GTK_BOX(hbox3), label_mdp, FALSE, TRUE, 0);



    GtkWidget* mdp = NULL;
    mdp = gtk_entry_new();

    gtk_entry_set_visibility(GTK_ENTRY(mdp), FALSE);
    gtk_entry_set_icon_from_stock(GTK_ENTRY(mdp), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_DIALOG_AUTHENTICATION);
    gtk_entry_set_icon_activatable(GTK_ENTRY(mdp), GTK_ENTRY_ICON_PRIMARY, FALSE);
    gtk_box_pack_start(GTK_BOX(hbox3), mdp, FALSE, TRUE, 3);

/**** Creation d'un champ pour verfier le mot de passe ****/

    GtkWidget *hbox_verif = NULL;
    hbox_verif = gtk_hbox_new(TRUE, 2);
    gtk_box_pack_start(GTK_BOX (vbox), hbox_verif, FALSE, TRUE, 2);

    GtkWidget *label_mdp_verif = NULL;
    label_mdp_verif = gtk_label_new(NULL);

    GtkTooltips * bulle_verif;
    bulle_verif = gtk_tooltips_new();
    gtk_label_set_markup (GTK_LABEL (label_mdp_verif), "Vérification du mot de passe :");
    gtk_tooltips_set_tip(bulle_verif, label_mdp_verif, "Saisissez un mot de passe", NULL); // Bulle
    gtk_box_pack_start(GTK_BOX(hbox_verif), label_mdp_verif, FALSE, TRUE, 0);

    GtkWidget* mdp_verif = NULL;
    mdp_verif = gtk_entry_new();

    gtk_entry_set_visibility(GTK_ENTRY(mdp_verif), FALSE);
    gtk_entry_set_icon_from_stock(GTK_ENTRY(mdp_verif), GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_DIALOG_AUTHENTICATION);
    gtk_entry_set_icon_activatable(GTK_ENTRY(mdp_verif), GTK_ENTRY_ICON_PRIMARY, FALSE);
    gtk_box_pack_start(GTK_BOX(hbox_verif), mdp_verif, FALSE, TRUE, 1);

    /***** Choix crypter ou decrypter *****/

    Widget_Info info;
    info.combobox = combo2_algo;
    info.parcourir = parcourir;
    info.entry = mdp;
    info.verif_entry = mdp_verif;

    // Box pour le bouton CRYPTER

    GtkWidget *hbox_champ3 = NULL;
    hbox_champ3 = gtk_hbox_new(TRUE, 2);
    //bulle
    GtkTooltips * bulle2;
    bulle2 = gtk_tooltips_new();

    gtk_box_pack_start(GTK_BOX(vbox), hbox_champ3, FALSE, TRUE, 5);

    GtkWidget *b_crypter = NULL;
    b_crypter = gtk_button_new_with_label("Crypter");
    gtk_tooltips_set_tip(bulle2, b_crypter, "Algorithme de cryptage", NULL); // Bulle
    gtk_signal_connect (GTK_OBJECT (b_crypter), "clicked", G_CALLBACK (cliqueC), &info);

    gtk_box_pack_start(GTK_BOX(hbox_champ3), b_crypter, FALSE, TRUE, 0);

    // Box pour le bouton DECRYPTER

    // Bulle
    GtkTooltips * bulle3;
    bulle3 = gtk_tooltips_new();
    GtkWidget *b_decrypter = NULL;
    b_decrypter = gtk_button_new_with_label("Décrypter");
    gtk_tooltips_set_tip(bulle3, b_decrypter, "Algorithme de décryptage", NULL); // Bulle
    gtk_signal_connect (GTK_OBJECT (b_decrypter), "clicked", G_CALLBACK (cliqueD), &info);

    gtk_box_pack_start(GTK_BOX(hbox_champ3), b_decrypter, FALSE, TRUE, 1);

    /***** Personnalisation de la fenetre *****/

    gtk_window_set_title(GTK_WINDOW(fenetrePrincipale), "CLYD"); // Titre de la fenêtre
    gtk_window_set_icon_from_file(GTK_WINDOW(fenetrePrincipale), "./image/icon.png", NULL); // Icône de l'application
    gtk_widget_show_all(fenetrePrincipale);
    g_signal_connect(G_OBJECT(fenetrePrincipale), "delete-event", G_CALLBACK(gtk_main_quit), NULL);

    gtk_main();

}
